<template>
  <div class="simple"
       v-loading="loading">
    <div v-if="infoFlow">
      <div v-if="editFlow"
           class="simple-view-info">
        <el-button icon="el-icon-close"
                   @click="editFlow = false"></el-button>
        <el-button icon="el-icon-check"
                   type="primary"
                   @click="confirm"></el-button>
      </div>
      <div v-else
           class="simple-view-info">
        <el-button @click="openEdit"
                   v-if="!isCompleted">{{$t('processDialog.editFlowChat')}}</el-button>
        <el-button icon="el-icon-back"
                   @click="showInfo(false)"></el-button>
      </div>
      <processDrag boxId="simple_flow"
                   ref="processDrag1"
                   :nodeList="nl"
                   :lineList="ll"
                   :tempId="tempId"
                   :orgId="orgId"
                   :status="statusArray"
                   :approvalData="approvalData"
                   :busiOption="busiOption"
                   :editFlow="editFlow"
                   :nodeMaintain="true"
                   :lastNode="this.nodeList[this.nodeList.length - 1]"
                   :limitNode="this.nodeList"
                   @changeLineList="changeLineList"
                   @updateFlow="updateFlow"></processDrag>
    </div>
    <div v-else>
      <div class="simple-view-info">
        <el-button @click="showInfo(true)">{{$t('processDialog.viewFlowChat')}}</el-button>
      </div>
      <flow :boxId="'simple'"
            :option="option"
            :nodeMaintain="false"
            :simple="true"
            :isDrag="false"
            :lastNode="this.nodeList[this.nodeList.length - 1]"
            @clickNode="handleClick"
            ref="simpleFlow"></flow>
      <el-scrollbar class="simple-introduce">
        <div class="handle"
             v-show="approval.opinion.length>0">
          <p class="color-span mar">{{$t('processDialog.treatment')}}</p>
          <el-table border
                    :data="approval.opinion">
            <el-table-column :label="$t('processDialog.receivingTime')"
                             prop="acceptTime"
                             align="center"></el-table-column>
            <el-table-column :label="$t('processDialog.handler')"
                             prop="creater"
                             align="center"></el-table-column>
            <el-table-column :label="$t('processDialog.handlerTime')"
                             prop="createTime"
                             align="center"></el-table-column>
            <el-table-column :label="$t('processDialog.handlerRange')"
                             prop="spendTime"
                             align="center">
              <template slot-scope="scope">
                {{scope.row.spendTime?scope.row.spendTime+$t('processDialog.hour'):''}}
              </template>
            </el-table-column>
            <el-table-column :label="$t('processDialog.decision')"
                             prop="lineName"
                             align="center"></el-table-column>
            <el-table-column :label="$t('processDialog.decisionOpinion')"
                             prop="opinion"
                             align="center"></el-table-column>
          </el-table>
        </div>
        <br>
        <div v-for="item in approval.basicTable"
             :key="item.id">
          <p class="color-span mar">{{item.formName}}</p>
          <customFields :updateData="item.sysFormField"
                        :disabled="true"
                        :inline="true"
                        :form="item.form"></customFields>
        </div>
      </el-scrollbar>
    </div>
  </div>
</template>

<script>
import flow from './flow'
import { deepClone } from '../../util/util'
import { getInstanceInfo, updateFlow, getInstanceNode } from '../../api/processManagement/flowInstance'
import processDrag from './index'
import { getWfStatusPage } from '../../api/processManagement/flowStatus'
import { getFieldById } from '../../api/processManagement'
import customFields from '../customFields'

export default {
  components: { flow, processDrag, customFields },
  props: {
    nodeList: {
      type: Array,
      default: []
    },
    lineList: {
      type: Array,
      default: []
    },
    tempId: {
      type: Number
    },
    orgId: {
      type: Number
    },
    status: {
      type: Array,
      default: []
    },
    approvalData: {
      type: Array,
      default: []
    },
    busiOption: {
      type: Array,
      default: []
    },
    instanceId: {
      type: Number
    },
    isCompleted: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    nodeList: {
      handler () {
        if (this.loadNodeData) return
        this.infoFlow = false
        this.option.nodeList = deepClone(this.nodeList)
        this.option.lineList = deepClone(this.lineList)
        if (this.$refs.simpleFlow)
          this.$refs.simpleFlow.loadView(this.nodeList, this.lineList, false)
        this.loadNodeData = true
        this.loading = false
      },
      deep: true
    },
    status: {
      handler () {
        this.statusArray = []
        this.status.some(res => {
          for (const k in res) this.statusArray.push({
            statusName: res[k],
            id: ~~k
          })
        })
      },
      deep: true
    }
  },
  data () {
    return {
      option: {
        lineList: deepClone(this.lineList),
        nodeList: deepClone(this.nodeList),
        width: '100%',
        height: '300px'
      },
      nl: [],
      ll: [],
      loadNodeData: false,
      approval: {
        opinion: [],
        basicTable: []
      },
      infoFlow: false,
      editFlow: false,
      statusArray: [],
      loading: true
    }
  },
  methods: {
    changeLineList (lineList) {
      this.ll = lineList.map(res => {
        const obj = {
          ...res,
          tempId: this.currentId,
          objStatusTo: res.objStatusTo || null, // 对象状态更改至
          condition: res.condition || null, // 分支条件
          wfStatusTo: res.wfStatusTo || null, // 流程状态更改至 
        }
        return obj
      })
    },
    handleClick (node) {
      if (node.nodeName === this.$t('processDialog.nodeName.start') || node.nodeName === this.$t('processDialog.nodeName.end') || this.nodeList[this.nodeList.length - 1].id === node.id) return
      this.loading = true
      getInstanceInfo(node.id).then(res => {
        this.loading = false
        if (res.data.data) {
          this.approval.opinion = res.data.data.opinion
          this.approval.basicTable = []
          if (Array.isArray(res.data.data.formRelation))
            res.data.data.formRelation.some(res2 => {
              this.getTableField(res2).then(res3 => {
                this.approval.basicTable.push(this.getFormValue(res3, res.data.data.formData))
              })
            })
        }
      })
    },
    getFormValue (source, data) {
      const sysFormField = []
      const form = {}
      data.some(res => {
        if (res.formId === source.id) {
          sysFormField.push(res)
          form[res.id] = res.fieldVal
        }
      })
      return {
        ...source,
        sysFormField,
        form
      }
    },
    getTableField (obj) {
      return new Promise((resolve, reject) => {
        getFieldById({ id: obj.formId }).then(res => {
          resolve(res.data.data)
        })
      })
    },
    showInfo (flag) {
      this.infoFlow = flag
      this.editFlow = false
      if (flag) {
        this.ll = []
        this.nl = []
        getInstanceNode(this.instanceId).then(res => {
          if (res.data.data) {
            this.$refs.processDrag1.loadNodeData = false
            this.ll = res.data.data.lines
            this.nl = res.data.data.nodes
          }
        })
      }
    },
    updateFlow () {
      getInstanceNode(this.instanceId).then(res => {
        if (res.data.data) {
          this.ll = res.data.data.lines
          this.nl = res.data.data.nodes
        }
      })
    },
    openEdit () {
      this.editFlow = true
    },
    // 检查流程图是否完整
    checkTempNode () {
      let result = false
      let startNode = true
      let endNode = true
      let parallelRule = false
      this.nl.some(res => {
        let fromId = false
        let toId = false
        this.ll.some(res2 => {
          if (fromId && toId) return true
          if (`${res2.fromId}` === `${res.id}`) fromId = true
          if (`${res2.toId}` === `${res.id}`) toId = true
        })
        if (fromId && toId) result = true // 判断普通节点
        else if (res.nodeName === this.$t('processDialog.nodeName.start') && !toId && fromId) result = true // 判断开始节点是否有下属节点
        else if (res.nodeName === this.$t('processDialog.nodeName.end') && toId && !fromId) result = true // 判断结束节点是否有上属节点
        else {
          this.$message.warning(`${this.$t('processDialog.error')}-${res.nodeName}${fromId ? '' : `-${this.$t('processDialog.noInLine')}`}${toId ? '' : this.$t('processDialog.noOutLine')}`)
          result = false
          return true
        }
        if (res.nodeName === this.$t('processDialog.nodeName.start') && startNode) startNode = false
        if (res.nodeName === this.$t('processDialog.nodeName.end') && endNode) endNode = false
        // 检查会签节点并行规则
        if (res.nodeType === 4 && res.ctsConditions.length > 0) {
          const appSet = new Set()
          const nodeSet = new Set()
          res.ctsConditions.some((res, index) => {
            appSet.add(res.approvalsCnt === 0 || res.approvalsCnt === '' ? index : res.approvalsCnt)
            nodeSet.add(res.ctsNodeId === '' ? index : res.ctsNodeId)
          })
          if (appSet.size !== nodeSet.size) parallelRule = true
        }
      })
      if (result) {
        if (startNode) {
          this.$message.warning(this.$t('processDialog.pleaseSelectStartNode'))
          return false
        }
        if (endNode) {
          this.$message.warning(this.$t('processDialog.pleaseSelectEndNode'))
          return false
        }
        if (parallelRule) {
          this.$message.warning(this.$t('processDialog.passRuleCannotSame'))
          return false
        }
        if (new Set(this.ll.map(res => {
          return `${res.fromId}` + `${res.toId}`
        })).size !== this.ll.length) {
          this.$message.warning(this.$t('processDialog.cannotMultiFlows'))
          return false
        }
      }
      return result
    },
    confirm () {
      if (this.checkTempNode()) {
        this.editFlow = false
        this.ll.some(res => {
          res.instanceId = this.instanceId
        })
        updateFlow({ instanceId: this.instanceId, lineList: this.ll, nodeList: this.nl }).then(res => {
          this.$message({
            type: res.data.meta.success ? 'success' : 'error',
            message: res.data.meta.message
          })
        })
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.simple {
  position: relative;
  margin-top: 1px;
  &-introduce {
    height: 315px;
    padding: 20px 20px 0 20px;
  }
  .mar {
    margin-bottom: 10px;
  }
  &-view-info {
    position: absolute;
    right: 10px;
    top: 10px;
    z-index: 999;
  }
}
</style>